import type { ParentAPI } from 'postmate'
import type { MaybeRef, Ref } from 'vue'
import Postmate from 'postmate'

export function usePostmateParent<
  T extends Pick<ParentAPI, 'call' | 'on' | 'get'>,
>({
  container,
  url,
  classListArray,
}: {
  container: Ref<HTMLDivElement | undefined>
  url: MaybeRef<string | undefined>
  classListArray?: MaybeRef<string[]>
}) {
  const parentInstance = shallowRef<Pick<ParentAPI, 'destroy' | 'frame'> & T>()
  const postmate = shallowRef<Postmate>()
  watch(
    [container, () => unref(url), () => unref(classListArray)],
    ([container, url, classListArray]) => {
      parentInstance.value?.destroy()
      parentInstance.value = undefined
      postmate.value = undefined
      if (container && url) {
        postmate.value = new Postmate({
          container, // Element to inject frame into
          url, // Page to load, must have postmate.js. This will also be the origin used for communication.
          classListArray, // Classes to add to the iframe via classList, useful for styling.
        })
        postmate.value.then((instance) => {
          parentInstance.value = instance as Pick<
            ParentAPI,
            'destroy' | 'frame'
          > &
          T
        })
      }
    },
    {
      immediate: true,
    },
  )

  onUnmounted(() => {
    parentInstance.value?.destroy()
    parentInstance.value = undefined
  })
  return parentInstance
}
